#pragma once
#include <iostream>
#include <map>
#include "base.hpp"
#include "data.hpp"

enum DiffType { DIFF_TYPE_SAME, DIFF_TYPE_ADD, DIFF_TYPE_DELETE, DIFF_TYPE_MODIFY };

struct DiffFile {
    std::string file_name;
    std::string elem_one_oid;
    std::string elem_two_oid;
    DiffType diff_type;
    std::string parent_oid = "";

    std::string to_string() {
        std::stringstream ss;
        switch (diff_type) {
        case DIFF_TYPE_SAME:
            ss << "no changes: " << file_name;
            break;
        case DIFF_TYPE_ADD:
            ss << "new file: " << file_name;
            break;
        case DIFF_TYPE_DELETE:
            ss << "deleted file: " << file_name;
            break;
        case DIFF_TYPE_MODIFY:
            ss << "modified file: " << file_name;
            break;
        }
        return ss.str();
    }
};

std::map<std::string, DiffFile> diff_trees(std::string blob_id_one, std::string blob_id_two);
std::map<std::string, DiffFile> diff_staged_tree(std::string blob_id_one);

std::map<std::string, DiffFile> diff_current_tree(std::string blob_id_one);
std::string diff_files(const std::string file1, const std::string file2,
                       const std::string file1_path, const std::string file2_path);
std::string diff_current_files(const std::string file1, const std::string file2,
                               const std::string file1_path, const std::string file2_path);
void merge_two_commit(std::map<std::string, DiffFile> &file_map);
std::string get_common_ancestor(std::string commit_one, std::string commit_two);
std::set<std::string> get_commit_ancestors(std::string commit_oid);
void diff_build_parent_oid(std::map<std::string, DiffFile> &file_map, std::string parent_obj_oid);